#include <iostream>
#include <string>


using namespace std;


//
// Clases
//

class cPerson {
	string m_name;
	int m_age;
	
public:
	
	// Para que funcione el constructor y el CC, parece que el argumento del CC
	// debe ser const
	// EN ESTE CASO PASA ESO
	cPerson(string name="NN",int age =0) {m_name = name; m_age = age;}
	~cPerson() {m_name = "";}
	string GetName(void) const {return m_name;}
	int GetAge(void) const {return m_age;} 	

	// Copy-Constructor
	cPerson(cPerson& persona) : m_name(persona.m_name), m_age(persona.m_age) {
		std::cout << "Invocando al Copy-Contructor" << std::endl;
	}
};


//
// Funciones Auxiliares
//

// Copy-Constructor invocado mediante el pasaje de argumento por valor
void PrintData(cPerson p) {
	
	string name = p.GetName();
	int age = p.GetAge();
	std::cout << "Nombre: " << name << "  " << "Edad: " << age << std::endl;
}


// Copy-Constructor invocado mediante el retorno por valor
cPerson NewPerson(string name, int age) {
	
	// El CC noes invocado cuando creo un objeto local a la funcion y lo retorno
	//cPerson p
	//return p;
	
	cPerson p(name, age);

	return p;
}

cPerson NewPersonCC(cPerson p) {
	return p;
}


//
// Main
//

int main(void) {
	
	cPerson Nicolas("Nicolas", 21);
	
	// Invocamos al CC e imprimimos los datos
	PrintData(Nicolas);

	// Los datos se copian en Mariano pero no se invoca al CC, pq el mensaje "Invocando al Copy-Constructor"
	// no aparece, por lo tanto debe ser una copia de bits (bitcopy)
	cPerson Mariano = NewPerson("Mariano", 19);
	
	// Invocamos al CC e imprimimos los datos
	PrintData(Mariano);

	// Invocamos al Copy-Constructor
	cPerson MarianoGemelo = Mariano;
	
	// Invocamos al CC e imprimimos los datos
	PrintData(MarianoGemelo);
	
	// Utilizamos la funcion que retorna por valor usando el CC
	Mariano = NewPersonCC(MarianoGemelo);

	return 0;
}
